package com.lottery.utils;

import java.util.ArrayList;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import com.lottery.service.pc28.customService.CostomerClient;
import com.lottery.service.pc28.customService.CostomerServer;
import com.lottery.service.pc28.customService.CostomerSystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.lottery.entity.CommunionMsg;

@Component
public class CustomerContext {

	// 日志
	private final static Logger logger = LoggerFactory.getLogger(CustomerContext.class);
	// 创建单列
	private static CustomerContext instance = null;

	// 客服自动分配的最大人数
	public static int maxAutoServerCount = 3;

	// 客服服务的最大人数
	public static int maxServerCount = 10;

	// 客服自动分配的最大人数
	// @Value("${MAXAUTOSEVICE}")
	// private String MAXAUTOSEVICE;

	// // 客服服务的最大人数
	// @Value("${MAXSERVICE}")
	// public static int maxServerCount;

	// 客服信息
	private ConcurrentHashMap<Integer, CostomerServer> serversMap;

	// 客户信息
	private ConcurrentHashMap<Integer, CostomerClient> clientMap;

	// 客户服务请求的的队列
	// private ConcurrentLinkedQueue<ServiceResquest> serviceRequestList;
	private ArrayList<Integer> serviceRequestList;

	private Lock lock;

	private ConcurrentHashMap<Integer, CostomerSystem> serverSystemMap;

	// 初始化
	private CustomerContext() {
		logger.debug("create CustomerContext");
		serversMap = new ConcurrentHashMap<Integer, CostomerServer>();
		clientMap = new ConcurrentHashMap<Integer, CostomerClient>();
		serviceRequestList = new ArrayList<Integer>();
		lock = new ReentrantLock();
		serverSystemMap = new ConcurrentHashMap<Integer, CostomerSystem>();
	}

	// 获取实例
	public static synchronized CustomerContext getInstance() {
		if (instance == null) {
			instance = new CustomerContext();
		}
		return instance;
	}

	// 获取等待人数
	public int getserviceRequestListSize() {
		return serviceRequestList.size();
	}

	public ArrayList<Integer> getserviceRequestList() {
		return serviceRequestList;
	}

	public ConcurrentHashMap<Integer, CostomerServer> getServersMap() {
		return serversMap;
	}

	public ConcurrentHashMap<Integer, CostomerClient> getClientMap() {
		return clientMap;
	}

	public ArrayList<CommunionMsg> getServerSystemMsg(int serverId) {
		if (!serverSystemMap.containsKey(serverId))
			return null;

		ArrayList<CommunionMsg> msgs = new ArrayList<CommunionMsg>();
		for (CommunionMsg one : serverSystemMap.get(serverId).getMessageList()) {
			msgs.add(one);
		}
		serverSystemMap.get(serverId).getMessageList().clear();

		return msgs;
	}

	/**
	 * 客服上线
	 * 
	 * @param serverId
	 *            客服 id
	 */
	public void serverOnline(int serverId, int maxServer) {
		if (!serversMap.containsKey(serverId)) {
			logger.debug("first serverOnline: " + serverId);
			serversMap.put(serverId, new CostomerServer(serverId, maxServer));
			serverSystemMap.put(serverId, new CostomerSystem());
		}
	}

	/**
	 * 客服下线
	 * 
	 * @param serverId
	 *            客服id
	 */
	public void serverOffline(int serverId) {

		Map<Integer, ArrayList<CommunionMsg>> costomerServer = serversMap.get(serverId).getMessageList();
		for (Entry<Integer, ArrayList<CommunionMsg>> entity : costomerServer.entrySet()) {
			int userId = entity.getKey();
			finishService(serverId, userId);
		}

		if (serversMap.containsKey(serverId)) {
			serversMap.remove(serverId);
		}
		if (serverSystemMap.containsKey(serverId)) {
			serverSystemMap.remove(serverId);
		}
	}

	/**
	 * 客户发起交互
	 * 
	 * @param userId
	 *            客户id
	 */
	public void userGetServer(int userId, int serverId) {
		if (!clientMap.containsKey(userId)
				|| (clientMap.containsKey(userId) && clientMap.get(userId).getServerId() == 0)) {
			logger.info("*************new clientMsg{}-{}", userId, serverId);
			CostomerClient costomerClient = new CostomerClient();
			costomerClient.setId(userId);
			costomerClient.setServerId(serverId);
			clientMap.put(userId, costomerClient);
		}
	}

	public boolean serverIdle(int serverId, byte idle) {
		if (!serversMap.containsKey(serverId)) {
			return false;
		}
		serversMap.get(serverId).setIsIdle(idle);

		if (serversMap.get(serverId).getCount() >= CustomerContext.maxAutoServerCount || serviceRequestList.isEmpty()) {
			return true;
		}

		lock.lock();
		int userId = serviceRequestList.get(0);
		serviceRequestList.remove(serviceRequestList.indexOf(userId));
		lock.unlock();

		serversMap.get(serverId).ServerCountAdd();
		ArrayList<CommunionMsg> clientMsg = new ArrayList<CommunionMsg>();
		serversMap.get(serverId).getMessageList().put(userId, clientMsg);
		userGetServer(userId, serverId);

		String dataNow = DateUtil.getFormatDate("yyyy-MM-dd HH:mm:ss");
		String msg = "客户" + userId + "需要您的帮助 ";

		CommunionMsg communionMsg = new CommunionMsg();
		communionMsg.setMsg(msg);
		communionMsg.setMsgid(0);
		communionMsg.setScrId(userId);
		communionMsg.setDstId(serverId);
		communionMsg.setSendTime(dataNow);
		serverSystemMap.get(serverId).getMessageList().add(communionMsg);

		msg = "您好，客服 " + serverId + "很高兴为您服务";
		serverSendMsg(serverId, userId, 0, msg, dataNow); // 系统消息msgid为 0

		return true;
	}

	/**
	 * 客户完成服务
	 * 
	 * @param userId
	 *            客户id
	 */
	public void userFinishServer(int userId) {

		lock.lock();
		int index = serviceRequestList.indexOf(userId);
		if (index != -1) {
			logger.debug("userFinishServer delete queue: " + userId);
			serviceRequestList.remove(index);
			lock.unlock();
			return;
		}
		lock.unlock();

		if (!clientMap.containsKey(userId)) {
			return;
		}
		int serverId = clientMap.get(userId).getServerId();
		clientMap.remove(userId);

		String dataNow = DateUtil.getFormatDate("yyyy-MM-dd HH:mm:ss");
		String msg = "客户已经结束会话，请关闭窗口！";
		userSendMsg(userId, serverId, -1, msg, dataNow);
		logger.debug("userFinishServer:{}-{}-{}", userId, serverId, msg);
	}

	private void addRequestQueen(int userId) {

		if (!serviceRequestList.contains(userId))
			serviceRequestList.add(userId);
	}

	/**
	 * 分配server
	 * 
	 * @param userId
	 * @return 服务ID
	 */
	public int allocateServer(int userId) {

		logger.debug("serversMap size:" + serversMap.size());
		if (serversMap.size() == 0) { // 没有客服在线
			return -1;
		}

		if (clientMap.containsKey(userId) && clientMap.get(userId).getServerId() != 0) {
			logger.debug("the old server");
			int server = clientMap.get(userId).getServerId(); // 正常情况进来不了
			if (serversMap.containsKey(server) && serversMap.get(server).getMessageList().containsKey(userId)) {
				String dataNow = DateUtil.getFormatDate("yyyy-MM-dd HH:mm:ss");
				String msg = "您好，客服 " + server + "很高兴为您服务";
				serverSendMsg(server, userId, 0, msg, dataNow); // 系统消息msgid为 0
				return server;
			}
		}

		if (0 == CustomerContext.maxAutoServerCount) {
			logger.debug("allocateServer max 0");
			addRequestQueen(userId);
			return -2;
		}

		int serverNum = 100;
		int serverId = 0;
		for (Entry<Integer, CostomerServer> entity : serversMap.entrySet()) {
			CostomerServer costomerServer = entity.getValue();
			if (costomerServer.getCount() < serverNum && costomerServer.getIsIdle() == 0) {
				serverNum = costomerServer.getCount();
				serverId = costomerServer.getId();
			}
		}

		if (serverNum >= CustomerContext.maxAutoServerCount) {
			addRequestQueen(userId);
			logger.debug("allocateServer autofull {}", serversMap.size());
			return -2;
		}

		serversMap.get(serverId).ServerCountAdd();
		ArrayList<CommunionMsg> clientMsg = new ArrayList<CommunionMsg>();
		serversMap.get(serverId).getMessageList().put(userId, clientMsg);
		userGetServer(userId, serverId);

		// Date date = new Date();
		// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		// String dataNow = sdf.format(date);
		String dataNow = DateUtil.getFormatDate("yyyy-MM-dd HH:mm:ss");
		String msg = "客户" + userId + "需要您的帮助 ";
		// userSendMsg(userId, serverId, 0, msg, dataNow);

		CommunionMsg communionMsg = new CommunionMsg();
		communionMsg.setMsg(msg);
		communionMsg.setMsgid(0);
		communionMsg.setScrId(userId);
		communionMsg.setDstId(serverId);
		communionMsg.setSendTime(dataNow);
		serverSystemMap.get(serverId).getMessageList().add(communionMsg);

		msg = "您好，客服 " + serverId + "很高兴为您服务";
		serverSendMsg(serverId, userId, 0, msg, dataNow); // 系统消息msgid为 0

		return serverId;
	}

	/**
	 * 用户发送消息
	 * 
	 * @param serverId
	 * @param userId
	 * @param msg
	 * @param sendTime
	 */
	public boolean userSendMsg(int userId, int serverId, int msgId, String msg, String sendTime) {
		if (!serversMap.containsKey(serverId)) {
			return false;
		}
		CommunionMsg communionMsg = new CommunionMsg();
		communionMsg.setMsgid(msgId);
		communionMsg.setScrId(userId);
		communionMsg.setDstId(serverId);
		communionMsg.setSendTime(sendTime);
		communionMsg.setMsg(msg);
		serversMap.get(serverId).getMessageList().get(userId).add(communionMsg);
		return true;
		// Lock lock = serversMap.get(serverId).getLock();
		// try {
		// lock.lock();
		// serversMap.get(serverId).getMessageList().add(communionMsg);
		// } finally {
		// lock.unlock();
		// }

	}

	/**
	 * 客服发送消息
	 * 
	 * @param userId
	 * @param msg
	 * @param sendTime
	 */
	public boolean serverSendMsg(int serverId, int userId, int msgId, String msg, String sendTime) {

		if (!clientMap.containsKey(userId)) {
			logger.error("***********userid not fund {}", userId);
			return false;
		}

		/************ 校验客服 *************/
		if (clientMap.get(userId).getServerId() != serverId) {
			logger.debug("serverId:{}:{}", clientMap.get(userId).getServerId(), serverId);
			String dataNow = DateUtil.getFormatDate("yyyy-MM-dd HH:mm:ss");
			String msg1 = "客户已经结束会话，请关闭窗口！";
			userSendMsg(userId, serverId, -1, msg1, dataNow);
			return false;
		}
		/*********************************/

		CommunionMsg communionMsg = new CommunionMsg();
		communionMsg.setMsgid(msgId);
		communionMsg.setScrId(serverId);
		communionMsg.setDstId(userId);
		communionMsg.setSendTime(sendTime);
		communionMsg.setMsg(msg);
		clientMap.get(userId).getMessageList().add(communionMsg);

		serversMap.get(serverId).getMessageList().get(userId).add(communionMsg);
		return true;

		// Lock lock = clientMap.get(userId).getLock();
		// try {
		// lock.lock();
		// clientMap.get(userId).getMessageList().add(communionMsg);
		// } finally {
		// lock.unlock();
		// }

	}

	/**
	 * 用户拉去客服发送的消息
	 * 
	 * @param userId
	 *            客户 id
	 * @return
	 */
	public ArrayList<CommunionMsg> userPullMsg(int userId) {
		// 加锁
		// Lock lock = clientMap.get(userId).getLock();
		ArrayList<CommunionMsg> userMsg = new ArrayList<CommunionMsg>();
		// try {
		// lock.lock();
		if (clientMap.containsKey(userId)) {
			for (CommunionMsg msg : clientMap.get(userId).getMessageList()) {
				userMsg.add(msg);
			}
			clientMap.get(userId).getMessageList().clear();
			return userMsg;
		}
		// }finally
		//
		// {
		// lock.unlock();
		// }
		// 解锁
		return null;
	}

	/**
	 * 客服拉去用户发送 的消息
	 * 
	 * @param serverId
	 *            客服id
	 * @return
	 */
	public ArrayList<CommunionMsg> serverPullMsg(int serverId, int userId) {
		// 加锁
		// Lock lock = serversMap.get(serverId).getLock();
		ArrayList<CommunionMsg> clientsMsg = new ArrayList<CommunionMsg>();

		ArrayList<CommunionMsg> msgs = serversMap.get(serverId).getMessageList().get(userId);

		if (msgs == null) {
			CommunionMsg one = new CommunionMsg();
			one.setDstId(serverId);
			one.setScrId(userId);
			one.setMsgid(-1);
			one.setMsg("客户已经结束会话，请关闭窗口！");
			one.setSendTime(DateUtil.getFormatDate("yyyy-MM-dd HH:mm:ss"));
			clientsMsg.add(one);
		} else {
			for (CommunionMsg one : msgs) {
				if (!one.isBePull() && one.getDstId() == serverId) {
					clientsMsg.add(one);
					one.setBePull(true);
				}
			}
		}

		// try {
		// lock.lock();
		// for (Entry<Integer, ArrayList<CommunionMsg>> clientMsgMap :
		// serversMap.get(serverId).getMessageList()
		// .entrySet()) {
		// ArrayList<CommunionMsg> userMsg = new ArrayList<CommunionMsg>();
		// int clientId = clientMsgMap.getKey();
		// ArrayList<CommunionMsg> msgs = clientMsgMap.getValue();
		// for (CommunionMsg msg : msgs) {
		// if (!msg.isBePull() && msg.getDstId() == serverId) {
		// userMsg.add(msg);
		// msg.setBePull(true);
		// }
		//
		// }
		// clientsMsg.put(clientId, userMsg);
		// }
		// serversMap.get(serverId).getMessageList().clear();
		// }finally
		//
		// {
		// lock.unlock();
		// }
		// 解锁
		return clientsMsg;
	}

	/**
	 * 客服服务完成
	 * 
	 * @param serverId
	 *            客服id
	 * @param userId
	 *            客户 id
	 */
	public void finishService(int serverId, int userId) {
		// 当客服完成和客户对话时
		String dataNow = DateUtil.getFormatDate("yyyy-MM-dd HH:mm:ss");
		String msg = "您好，本次服务结束，祝您生活愉快";
		if (clientMap.containsKey(userId)) {
			serverSendMsg(serverId, userId, -1, msg, dataNow);
			if (clientMap.get(userId).getServerId() == serverId) {
				clientMap.get(userId).setServerId(0);
			}
		}
		serversMap.get(serverId).getMessageList().remove(userId);
		serversMap.get(serverId).ServerCountReduce();
	}

	/**
	 * 客服抓取客户
	 * 
	 * @param serverId
	 *            客服id
	 * @param userId
	 *            客户 id
	 */
	public int getClentId(int serverId, int userId) {

		if (serversMap.containsKey(serverId) && serversMap.get(serverId).getCount() > CustomerContext.maxServerCount) {
			return -1;
		}

		lock.lock();
		if (!serviceRequestList.contains(userId)) {
			lock.unlock();
			return 0;
		}
		// serviceRequestList.remove(userId);
		logger.debug("getClentId delete queue: " + userId);
		serviceRequestList.remove(serviceRequestList.indexOf(userId));
		lock.unlock();

		// Integer userId = serviceRequestList.poll();
		// if (userId == null) {
		// return 0;
		// }

		ArrayList<CommunionMsg> clientMsg = new ArrayList<CommunionMsg>();
		serversMap.get(serverId).getMessageList().put(userId, clientMsg);
		userGetServer(userId, serverId);

		String dataNow = DateUtil.getFormatDate("yyyy-MM-dd HH:mm:ss");
		String msg = "您好，客服 " + serverId + "很高兴为您服务";
		serverSendMsg(serverId, userId, 0, msg, dataNow); // 系统消息msgid为 0
		serversMap.get(serverId).ServerCountAdd();

		return userId;
	}

}